package com.evanst.bouncer;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.SpriteBackground;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.sensor.orientation.IOrientationListener;
import org.anddev.andengine.sensor.orientation.OrientationData;
import org.anddev.andengine.ui.activity.BaseGameActivity;

public class GameEngine implements IUpdateHandler, IOrientationListener {
	final private static GameEngine INSTANCE = new GameEngine();
	private GameWorld gameWorld;
	private Scene scene = null;
	private Camera mCamera;
	private static final int CAMERA_WIDTH = 480;
	private static final int CAMERA_HEIGHT = 320;
	private static final int GRID_SIZE = 16;
	
	private Texture backgroundTexture = null;
	private Texture playersTexture = null;
	private TextureRegion backgroundTextureRegion = null;
	private TextureRegion[] playerTextureRegions = new TextureRegion[GameWorld.getMaxPlayerCount()];
	private TextureRegion ballTextureRegion = null;
	private Sprite[] playerSprites = new Sprite[GameWorld.getMaxPlayerCount()];
	private Sprite ballSprite;
	private BaseGameActivity context = null;
	private Engine andEngine = null;
	
	public static GameEngine getInstance() {
		return INSTANCE;
	}

	public void initialize(BaseGameActivity context) {
		this.context = context;
		gameWorld = new GameWorld();
		gameWorld.initialize();
	}
	
	private int getScreenCoordinate(int actualCoordinate) {
		return (actualCoordinate * GRID_SIZE) + GRID_SIZE;
	}
	@Override
	public void onUpdate(float pSecondsElapsed) {
		for (int i = 0;i < GameWorld.getMaxPlayerCount();i++) {
			Player player = gameWorld.getPlayer(i);
			player.setX(player.getX() + player.getXTilt());
			player.setY(player.getY() + player.getYTilt());
			if (player.getX() >= GameWorld.getWidth()) {
				player.setX(GameWorld.getWidth() - 1);
			} else if (player.getX() < 0) {
				player.setX(0);
			}
			if (player.getY() >= GameWorld.getHeight()) {
				player.setY(GameWorld.getHeight() - 1);
			} else if (player.getY() < 0) {
				player.setY(0);
			}
			playerSprites[i].setPosition(getScreenCoordinate(player.getX()), getScreenCoordinate(player.getY()));
		}
		ballSprite.setPosition(getScreenCoordinate(gameWorld.getBall().getX()), getScreenCoordinate(gameWorld.getBall().getY()));
	}

	@Override
	public void reset() {
		// TODO Auto-generated method stub
		
	}
	
	public void loadResources() {
		TextureRegionFactory.setAssetBasePath("gfx/");
		backgroundTexture = new Texture(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		backgroundTextureRegion = TextureRegionFactory.createFromAsset(backgroundTexture, context, "field.png", 0, 0);
		playersTexture = new Texture(128, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		int i;
		for (i = 0;i < GameWorld.getMaxPlayerCount();i++) {
			playerTextureRegions[i] = TextureRegionFactory.createFromAsset(playersTexture, context, "player" + (i + 1) + ".png", i*32, 0);
			playerSprites[i] = new Sprite(0, 0, playerTextureRegions[i]);
		}
		ballTextureRegion = TextureRegionFactory.createFromAsset(playersTexture, context, "ball.png", i*32, 0);
		ballSprite = new Sprite(0, 0, ballTextureRegion);
		andEngine.getTextureManager().loadTextures(backgroundTexture, playersTexture);
		
	}
	
	public Engine loadAndEngine() {
		mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		andEngine = new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
		andEngine.enableOrientationSensor(context, this);
		return andEngine;
	}
	
	public Scene loadScene() {
		scene = new Scene(1);
		Sprite sprite = new Sprite(0, 0, backgroundTextureRegion);
		SpriteBackground spriteBackground = new SpriteBackground(sprite);
		scene.setBackground(spriteBackground);
		for (int i = 0;i < GameWorld.getMaxPlayerCount();i++) {
			scene.getLayer(0).addEntity(playerSprites[i]);
		}
		scene.getLayer(0).addEntity(ballSprite);
		scene.registerUpdateHandler(this);
		return scene;
	}

	@Override
	public void onOrientationChanged(OrientationData data) {
		Player humanPlayer = gameWorld.getPlayer(1);
		if (data.getPitch() > 15) {
			humanPlayer.setXTilt(-1);
		} else if (data.getPitch() < -15) {
			humanPlayer.setXTilt(1);
		} else {
			humanPlayer.setXTilt(0);	
		}
		
		if (data.getRoll() > 15) {
			humanPlayer.setYTilt(1);
		} else if (data.getRoll() < -15) {
			humanPlayer.setYTilt(-1);
		} else {
			humanPlayer.setYTilt(0);
		}
		
		
	}
}
